home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / win / c / dib.exe / DIB.CPP < prev    next >
C/C++ Source or Header  |  1991-11-10  |  6KB  |  226 lines

  1. #include "dib.h"
  2.  
  3. // --------------------------------------------------------------------------
  4. //    Author:        Patrick Reilly    70274,161
  5. //    Function:   freadDIBitmap
  6. //    Purpose:    Read a DIB bitmap (.bmp) file into a HBITMAP
  7. //    Arguments:    hdc -      HDC for your destination (ie screen)
  8. //                lpszSpec - file specification
  9. //                fn       - call-back function to modify colors. NULL if
  10. //                        no color mods required.
  11. //    Returns:    HBITMAP. NULL on error.
  12. // --------------------------------------------------------------------------
  13.  
  14. HBITMAP freadDIBitmap(HDC hdc,LPSTR lpszSpec,void (*fn)(RGBQUAD far *))
  15.     {
  16.     int hFile,nbRgb,n,nRgbQuad;
  17.     HBITMAP hBitmap;
  18.     GLOBALHANDLE hmem,hbmi;
  19.     char huge *hp,huge *hptr;
  20.     LPBITMAPINFO lpbmi;
  21.     LPBITMAPFILEHEADER lpbmfh;
  22.     LPBITMAPINFOHEADER lpbmih;
  23.     DWORD dwBitmapSize;
  24.     WORD wSize;
  25.     RGBQUAD far *lprgb;
  26.  
  27. // open bitmap file //
  28.     if((hFile = _lopen(lpszSpec,OF_READ)) == -1)    return 0;
  29.  
  30. // allocate block large enough to hold bitmapfileheader //
  31.  
  32.     if(!(hmem = GlobalAlloc(GMEM_MOVEABLE,sizeof(BITMAPFILEHEADER))))
  33.         {
  34.         _lclose(hFile);
  35.         return 0;
  36.         }
  37.     lpbmfh = (LPBITMAPFILEHEADER) GlobalLock(hmem);
  38.  
  39. // read the BITMAPFILEHEADER from file //
  40.  
  41.     if(_lread(hFile,(LPSTR)lpbmfh,sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))
  42.         {
  43.         _lclose(hFile);
  44.         GlobalLock(hmem);    GlobalFree(hmem);
  45.         return 0;
  46.         }
  47.  
  48. // ensure its a bitmap file //
  49.  
  50.     if( *((char far *)lpbmfh) != 'B' || *((char far *)(lpbmfh)+1) != 'M')
  51.         {
  52.         _lclose(hFile);
  53.         GlobalLock(hmem);    GlobalFree(hmem);
  54.         return 0;
  55.         }
  56.  
  57. // calculate bitmap size from BITMAPFILEHEADER //
  58.  
  59.     dwBitmapSize = lpbmfh->bfSize - lpbmfh->bfOffBits;
  60.  
  61. // dont need file header any more - free memory //
  62.  
  63.     GlobalLock(hmem);        GlobalFree(hmem);
  64.  
  65. // ensure bitmap size is legal //
  66.  
  67.     if(dwBitmapSize <= 0 || dwBitmapSize >= 67108864L)
  68.         {
  69.         _lclose(hFile);
  70.         return 0;
  71.         }
  72.  
  73. // allocate a BITMAPINFOHEADER and read from file //
  74.  
  75.     if(!(hmem = GlobalAlloc(GMEM_MOVEABLE,sizeof(BITMAPINFOHEADER))))
  76.         {
  77.         _lclose(hFile);
  78.         return 0;
  79.         }
  80.     lpbmih = (LPBITMAPINFOHEADER) GlobalLock(hmem);
  81.     if(_lread(hFile,(LPSTR)lpbmih,sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER))
  82.         {
  83.         GlobalLock(hmem);    GlobalFree(hmem);
  84.         _lclose(hFile);
  85.         return 0;
  86.         }
  87.  
  88. // calculate the number of RGBQUAD structures in file //
  89.  
  90.     if(!(nRgbQuad = lpbmih->biClrUsed))
  91.         nRgbQuad = 1 << lpbmih->biBitCount;
  92.  
  93. // reallocate BITMAPINFOHEADER memory to hold RGBQUADs - makes it a
  94. // BITMAPINFO structure instead
  95.  
  96.     GlobalLock(hmem);
  97.     if(!(hbmi = GlobalReAlloc(hmem,sizeof(BITMAPINFOHEADER)+nRgbQuad*sizeof(RGBQUAD)+2,GMEM_MOVEABLE)))
  98.         {
  99.         GlobalFree(hmem);
  100.         _lclose(hFile);
  101.         return 0;
  102.         }
  103.     lpbmi = (LPBITMAPINFO) GlobalLock(hbmi);
  104.  
  105. // read the RGBQUAD structures. if fn not NULL, call for each RGBQUAD //
  106.  
  107.     lprgb = (RGBQUAD far *) lpbmi->bmiColors;
  108.     for(n = 0; n < nRgbQuad; n++)
  109.         {
  110.         if(_lread(hFile,(LPSTR)lprgb,sizeof(RGBQUAD)) != sizeof(RGBQUAD))
  111.             {
  112.             GlobalLock(hbmi);    GlobalFree(hbmi);
  113.             _lclose(hFile);
  114.             return 0;
  115.             }
  116.         if(fn)
  117.             (*fn)(lprgb);
  118.         lprgb++;
  119.         }
  120.     GlobalLock(hbmi);
  121.  
  122. // allocate memory for the bitmap data //
  123.  
  124.     if(!(hmem = GlobalAlloc(GMEM_MOVEABLE,dwBitmapSize)))
  125.         {
  126.         GlobalFree(hbmi);
  127.         _lclose(hFile);
  128.         return 0;
  129.         }
  130.     hp = hptr = (char huge *) GlobalLock(hmem);
  131.  
  132. // read the bitmap from the file, casting a huge pointer to far pointer
  133. // for _lread and incrementing the huge pointer to keep it aligned
  134.  
  135.     while(dwBitmapSize > 0)
  136.         {
  137.         wSize = (dwBitmapSize >= 32768) ? 32768 : dwBitmapSize;
  138.         if(_lread(hFile,(LPSTR)hp,wSize) != wSize)
  139.             {
  140.             GlobalLock(hmem);    GlobalFree(hmem);
  141.             GlobalFree(hbmi);
  142.             _lclose(hFile);
  143.             return 0;
  144.             }
  145.         hp += wSize;
  146.         dwBitmapSize -= wSize;
  147.         }
  148.     _lclose(hFile);
  149.  
  150. // Create the DIB //
  151.  
  152.     lpbmi = (LPBITMAPINFO) GlobalLock(hbmi);
  153.     hBitmap = CreateDIBitmap(hdc,&lpbmi->bmiHeader,CBM_INIT,(LPSTR)hptr,lpbmi,DIB_RGB_COLORS);
  154.  
  155. // Free up memory //
  156.  
  157.     GlobalLock(hbmi);    GlobalFree(hbmi);
  158.     GlobalLock(hmem);    GlobalFree(hmem);
  159.  
  160. // done //
  161.  
  162.     return hBitmap;
  163.     }
  164.  
  165. // --------------------------------------------------------------------------
  166. //    Function:   freadDIBitmap
  167. //    Purpose:    Read a DIB bitmap (.bmp) file into a HBITMAP
  168. //    Arguments:    hdc -      HDC for your destination (ie screen)
  169. //                lpszSpec - file specification
  170. //    Returns:    HBITMAP. NULL on error.
  171. // --------------------------------------------------------------------------
  172.  
  173. HBITMAP freadDIBitmap(HDC hdc,LPSTR lpszSpec)
  174.     {
  175.  
  176. // call freadDIBitmap(HDC,LPSTR,void (*)(RGBQUAD far *)) with a NULL fn //
  177.  
  178.     return freadDIBitmap(hdc,lpszSpec,0);
  179.     }
  180.  
  181. // --------------------------------------------------------------------------
  182. //    Function:   fitBitmap
  183. //    Purpose:    Stretch contents of one bitmap onto another.
  184. //    Arguments:    hdc -      HDC for your destination (ie screen)
  185. //                hbmDest -  destination bitmap handle
  186. //                hbmSrc -   source bitmap handle
  187. //    Returns:    HBITMAP. NULL on error.
  188. // --------------------------------------------------------------------------
  189.  
  190. void fitBitmap(HDC hdc,HBITMAP hbmDest,HBITMAP hbmSrc)
  191.     {
  192.     HDC hdcSrc,hdcDest;
  193.     BITMAP bmSrc,bmDest;
  194.  
  195. // ensure handles are valid //
  196.     if(!hbmDest || !hbmSrc || !hdc)        return;
  197.  
  198. // create DCs to access bitmaps //
  199.  
  200.     hdcSrc = CreateCompatibleDC(hdc);
  201.     hdcDest = CreateCompatibleDC(hdc);
  202.     SelectObject(hdcSrc,hbmSrc);
  203.     SelectObject(hdcDest,hbmDest);
  204.  
  205. // use common mapping mode (pixel-based) //
  206.  
  207.     SetMapMode(hdcSrc,MM_TEXT);
  208.     SetMapMode(hdcDest,MM_TEXT);
  209.  
  210. // get BITMAP structs for both (contains size data) //
  211.  
  212.     GetObject(hbmSrc,sizeof(BITMAP),(LPSTR) &bmSrc);
  213.     GetObject(hbmDest,sizeof(BITMAP),(LPSTR) &bmDest);
  214.  
  215. // StretchBlt copy from source to destination //
  216.  
  217.     StretchBlt(hdcDest,0,0,bmDest.bmWidth,bmDest.bmHeight,
  218.             hdcSrc,0,0,bmSrc.bmWidth,bmSrc.bmHeight,SRCCOPY);
  219.  
  220. // housekeeping //
  221.  
  222.     DeleteDC(hdcDest);
  223.     DeleteDC(hdcSrc);
  224.     }
  225.  
  226.